/*
 * Grafo.cpp
 *
 *  Created on: 16/10/2012
 *      Author: vagner
 */

#include "Grafo.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>

namespace tp2cn {

Grafo::Grafo() {
	// do nothing

}

Grafo::Grafo(int numVertices){
	if(numVertices > 0){
		this->pVertice = Vertices (numVertices);
		this->MD = new MatrizDistancia(numVertices, numVertices,0.0);
		this->numVertices = numVertices;
		this->maxCapacidade = 0;
		this->minCapacidade = 0;
		this->maxDemanda = 0;
		this->minDemanda = 0;

	}else{
		std::cout << "Valor informando é invalido: " << numVertices << std::endl;
	}

}

Grafo::~Grafo() {
	//delete this->pVertice;
	//delete this->MD;
}

void Grafo::insereVertice(const Vertice& v){

	pVertice.push_back(v);
	if(v.capacidade < this->minCapacidade){
		this->minCapacidade = v.capacidade;
	}else if(v.capacidade > this->maxCapacidade){
		this->maxCapacidade = v.capacidade;
	}

	if(v.demanda < this->minDemanda){
		this->minDemanda = v.demanda;
	} else if (v.demanda > this->maxDemanda){
		this->maxDemanda = v.demanda;
	}

}

void Grafo::insereVerticeNaPosicao(const Vertice& v, int posicao){

	pVertice.at(posicao) = v;

	if(v.capacidade < this->minCapacidade){
			this->minCapacidade = v.capacidade;
		}else if(v.capacidade > this->maxCapacidade){
			this->maxCapacidade = v.capacidade;
		}

		if(v.demanda < this->minDemanda){
			this->minDemanda = v.demanda;
		} else if (v.demanda > this->maxDemanda){
			this->maxDemanda = v.demanda;
		}
}

void Grafo::showVertices(void) const{
	Vertices::const_iterator itVertices;

	for(itVertices = pVertice.begin(); itVertices < pVertice.end();itVertices++){
		std::cout << "ID Vértice: " << itVertices->idVertice << std::endl;
		std::cout << "Coordenada X: " << itVertices->coorX << std::endl;
		std::cout << "Coordenada Y: " << itVertices->coorY << std::endl;
		std::cout << "Capacidade: " << itVertices->capacidade << std::endl;
		std::cout << "Demanda: " << itVertices->demanda << std::endl;
		std::cout << "********************************"<<std::endl;

	}
}

void Grafo::calculaMatrizDistancia(){

	int numVertices = pVertice.size();
	Item auxItem;
	for(int i = 0;i<numVertices;i++){
		for(int j = 0; j < numVertices;j++){
			auxItem.valor.realValor = distanciaEntreVertices(pVertice.at(i),pVertice.at(j));
			MD->insereItem(auxItem,i,j);
		}
	}
}

void Grafo::calculaDistanciaVertice(int idVertice){
	int numVertices = pVertice.size();
	Item auxItem;

	for(int j = 0; j < numVertices;j++){
				auxItem.valor.realValor = distanciaEntreVertices(pVertice.at(idVertice),pVertice.at(j));
				MD->insereItem(auxItem,idVertice,j);
			}

}

void Grafo::showMatrizDistancia()const{
	MD->show();
}

int Grafo::getCapacidade(int idVertice){
	return pVertice.at(idVertice).capacidade;
}

void Grafo::setCapacidade(int idVertice, int capacidade){
	pVertice.at(idVertice).capacidade = capacidade;
}

int Grafo::getDemanda(int idVertice){

	return pVertice.at(idVertice).demanda;
}

int Grafo::getNumVertices(){
	return this->numVertices;
}

double Grafo::getDistancia(int vertic_1, int vertice_2){

	Item returnItem =	MD->getItem(vertic_1, vertice_2);


	return (returnItem.valor.realValor);

}

int Grafo::getMinDemanda(){
	return this->minDemanda;
}

int Grafo::getMaxDemanda(){
	return this->maxDemanda;
}

int Grafo::getMinCapacidade(){
	return this->minCapacidade;
}

int Grafo::getMaxCapacidade(){
	return this->maxCapacidade;
}

Vertice Grafo::getPontoMedio(){

	Vertice pontoMedio;
	pontoMedio.coorX = 0;
	pontoMedio.coorY = 0;
	std::vector<Vertice>::const_iterator itVertices;

	for(itVertices = pVertice.begin();itVertices != pVertice.end(); itVertices++){
		pontoMedio.coorX += itVertices->coorX;
		pontoMedio.coorY += itVertices->coorY;
	}

	pontoMedio.coorX = pontoMedio.coorX / this->numVertices;
	pontoMedio.coorY = pontoMedio.coorY / this->numVertices;

	return pontoMedio;

}

void Grafo::defineNovaVisita(int idVertice){
	//std::cout << "Definindo nova vista" << std::endl;
	this->pVertice.at(idVertice).numeroFormigas++;
}

Vertice Grafo::getVertice(int idVertice){

	//Recuperando um vertice
	//std::cout<< "Recuperando o vertice " << idVertice << std::endl;
	//std::cout << "Numero de vertices " << pVertice.size() << std::endl;
	return pVertice.at(idVertice);
}

bool Grafo::verticeAtendido(int idVertice){

	return (this->pVertice.at(idVertice).atendidoPor != N_ATENDIDO);

}

int Grafo::getMediana(int idVertice){
	return (this->pVertice.at(idVertice).atendidoPor);
}

void Grafo::setAtendimento(int idVertice, int idMediana){

	this->pVertice.at(idVertice).atendidoPor = idMediana;
}

} /* namespace tp2cn */
